import os
import json
import time
import xlrd
import xlwt as xlwt
from django.http import HttpResponse, FileResponse
from django.views.generic import ListView
from django.db.models import Q
from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import csrf_exempt

from automatic.management.models import UserAndProduct, Project, Module
from automatic.webinterface.models import *
from automatic.settings.common import interface

UPLOAD_ROOT = interface + '/dataconfig/'
interface_result = interface + '/result/'


# Create your views here.

class WebinterfaceListIndex(ListView):
    context_object_name = 'interfacelist'
    template_name = 'webinterface/webinterface.html'
    paginate_by = 10
    # raw_sql = "select * from autoplat_case where projectid_id in (select id from autoplat_project where productid_id in (select productname_id from autoplat_userandproduct where username_id=3));"
    casesum = 0
    model = Webinterface
    http_method_names = [u'get']

    def get_queryset(self):
        # 读取automagic/interfaceAPI/dataconfig/interface.xls的接口用例，写入数据库
        files = ''
        for file in files:
            pass

        # 读数据库获取接口用例列表
        prodcutid = UserAndProduct.objects.filter(username=self.request.user).values('productname')
        interfacelist = Webinterface.objects.filter(
            projectid__in=Project.objects.filter(productid__in=prodcutid).values('id')).order_by('-pk')
        prodcutid = self.request.GET.get('check_productname')
        projectid = self.request.GET.get('projectid')
        moduleid = self.request.GET.get('moduleid')
        casestatus = self.request.GET.get('casestatus')
        testresult = self.request.GET.get('testresult')
        keyword = self.request.GET.get('keyword')
        if prodcutid and int(prodcutid):
            interfacelist = interfacelist.filter(projectid__in=Project.objects.filter(productid=prodcutid).values('id'))
        if projectid:
            interfacelist = interfacelist.filter(projectid=projectid)
        if moduleid:
            interfacelist = interfacelist.filter(moduleid=moduleid)
        if casestatus:
            interfacelist = interfacelist.filter(isenabled=casestatus)
        if testresult:
            interfacelist = interfacelist.filter(actual=testresult)
        if keyword:
            interfacelist = interfacelist.filter(
                Q(pk__icontains=keyword) | Q(descr=keyword) | Q(createat__icontains=keyword))
        self.casesum = len(interfacelist)
        return interfacelist

    def get_context_data(self, **kwargs):
        context = super(WebinterfaceListIndex, self).get_context_data(**kwargs)
        context['projectlist'] = Project.objects.all().order_by('-sortby')
        context['modulelist'] = Module.objects.all().order_by('-sortby')
        context['userandproduct'] = UserAndProduct.objects.all()
        context['casesum'] = self.casesum
        return context


@csrf_exempt
@login_required()
def run_interface(request):
    if request.method == 'POST':
        post_dict = request.POST
        run_config_dic = {
            "projectid": post_dict['projectid'],
            "isenabled": post_dict['isenabled'],
            "smpt_address": post_dict['smpt_address'],
            "smpt_port": post_dict['smpt_port'],
            "email_user": post_dict['email_user'],
            "email_password": post_dict['email_password'],
            "receivers": post_dict['receivers']
        }

        projectid = run_config_dic.get('projectid')
        isenabled = run_config_dic.get('isenabled')
        smpt_address = run_config_dic.get('smpt_address')
        smpt_port = run_config_dic.get('smpt_port')
        email_user = run_config_dic.get('email_user')
        email_password = run_config_dic.get('email_password')
        receivers = run_config_dic.get('receivers')

        with open(interface + '/dataconfig/config.json', "r+", encoding='utf-8') as f:
            conf = json.load(f)
            if isenabled == "on":
                conf['email']['send_email'] = 'True'
                message = '开始执行接口用例测试，执行完成后按配置发送邮件，请查收。'
            else:
                conf['email']['send_email'] = 'False'
                message = '开始执行接口用例测试，本次测试不发送邮件，' \
                          '请查看/automagic/interfaceAPI/result目录下的测试结果文件。'
            conf['email']['smpt_address'] = smpt_address
            conf['email']['smpt_port'] = smpt_port
            conf['email']['email_user'] = email_user
            conf['email']['email_password'] = email_password
            conf['email']['receivers'] = receivers

            f.seek(0)  # rewind
            json.dump(conf, f, ensure_ascii=False)
            f.truncate()
            f.close()

        case_file = UPLOAD_ROOT + "interface-" + str(projectid) + '.xls'
        sys_time = time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime())
        result_file_name = "result_%s.xls" % sys_time
        result_file = os.path.join(interface_result, result_file_name)
        open(result_file, "wb").write(open(case_file, "rb").read())

        # 执行接口测试用例
        os.system("python3 %s/interfaceAPI/test_run.py --result_file %s" % (interface, result_file))
        # 读取结果文件写入数据库
        if os.path.exists(result_file):
            parse_xls(projectid, result_file)

        return HttpResponse(message)
    else:
        return HttpResponse('接口测试运行配置错误，执行测试失败！')


@csrf_exempt
@login_required()
def get_interface_history(request):
    interfacehistory = []
    webinterfaceid = request.GET['webinterfaceid']
    datalist = Webresponse.objects.filter(webinterfaceid=webinterfaceid).order_by('-id')[:20]
    for i in datalist:
        ih = {}
        ih['webinterfaceid'] = i.webinterfaceid.id
        ih['id'] = i.id
        ih['actual'] = i.actual
        ih['exectime'] = i.exectime
        ih['headers'] = i.headers
        ih['params'] = i.params
        ih['expected'] = i.expected
        ih['Response_content'] = i.Response_content
        interfacehistory.append(ih)
    return HttpResponse(json.dumps(interfacehistory))


@csrf_exempt
@login_required()
def file_down(request, file_name):
    """
    下载导入服务器模版
    :param request:
    :return:
    """
    projectid = (file_name.split('.')[0]).split('-')[1]
    modlist = Module.objects.filter(projectid=projectid, isenabled=True)
    file_path = os.path.join(interface, 'dataconfig', 'template')
    if not os.path.exists(file_path):
        os.mkdir(file_path)
    # file_path = interface + '/dataconfig/template/'
    file_name = 'interface-' + str(projectid) + '.xls'
    f = os.path.join(file_path, file_name)
    if os.path.exists(f):
        os.remove(f)
    excelTabel = xlwt.Workbook()
    style1 = xlwt.XFStyle()  # 设置单元格格式为文本
    style1.num_format_str = '@'
    config = excelTabel.add_sheet('config')
    config.write(0, 0, '测试环境（http://ip:port/）')
    config.write(1, 0, '登录接口')
    config.write(2, 0, '登录参数')
    for model in modlist:
        sheet_name = str(model.id) + '-' + str(model.name)
        model_sheet = excelTabel.add_sheet(sheet_name, cell_overwrite_ok=True)
        model_sheet.write(0, 0, '用例编号')
        model_sheet.write(0, 1, '用例描述')
        model_sheet.write(0, 2, '接口信息')
        model_sheet.write(0, 3, '请求方法')
        model_sheet.write(0, 4, '是否执行')
        model_sheet.write(0, 5, 'case依赖')
        model_sheet.write(0, 6, '依赖字段')
        model_sheet.write(0, 7, '依赖方式')
        model_sheet.write(0, 8, '请求参数')
        model_sheet.write(0, 9, '预期结果')
        model_sheet.write(0, 10, '实际结果')
        model_sheet.write(0, 11, '测试结果')
        model_sheet.write(0, 12, '执行时间')
    excelTabel.save(f)

    file = open(f, 'rb')
    response = FileResponse(file)
    response['Content-Type'] = 'application/octet-stream'
    response['Content-Disposition'] = 'attachment;filename="%s"' % file_name

    return response


def upload_file(request):
    """
    上传文件
    :param request:
    :return:
    """
    file_obj = request.FILES.get('file')
    # 创建upload文件夹
    if not os.path.exists(UPLOAD_ROOT):
        os.makedirs(UPLOAD_ROOT)
    try:
        if file_obj is None:
            return HttpResponse('请选择要上传的文件')
        file = os.path.join(UPLOAD_ROOT, file_obj.name)
        if os.path.exists(file):
            os.remove(file)
        # 循环二进制写入
        f = open(file, 'wb')
        for chunk in file_obj.chunks():
            f.write(chunk)
        f.close()
    except Exception as e:
        return HttpResponse(json.dumps({"code": 300, "msg": "上传文件失败"}))
    # 写入数据库
    file_path = UPLOAD_ROOT + file_obj.name
    return parse_xls('', file_path)


def parse_xls(projectid, file_path):
    try:
        readboot = xlrd.open_workbook(file_path)
    except FileNotFoundError:
        print('没有找到文件')
    addnum = 0
    updatenum = 0
    if projectid == '':
        projectid = int(file_path.split('interface-')[1].split('.')[0])
    project = Project.objects.filter(id=projectid)[0]
    for sheet_name in readboot.sheet_names():
        if sheet_name == 'config':
            sheet = readboot.sheet_by_name(sheet_name)
            environment = sheet.cell_value(0, 1)
            login_interface = sheet.cell_value(1, 1)
            login_param = sheet.cell_value(2, 1)

            config_list = Config.objects.filter(projectid=project)
            if config_list:
                for obj in config_list:
                    obj.delete()
            Config.objects.create(projectid=project, environment=environment,
                                  login_interface=login_interface, login_param=login_param)
        else:
            moduleid = int(sheet_name.split('-')[0])
            module = Module.objects.filter(id=moduleid)[0]
            sheet = readboot.sheet_by_name(sheet_name)
            nrows = sheet.nrows
            for i in range(1, nrows):
                row = sheet.row_values(i)
                interfaceid = int(row[0])
                url = row[2]
                method = row[4]
                dependent = row[5]
                if sheet.cell(i, 5).ctype == 2:
                    dependent = str(int(dependent))
                else:
                    pass
                dependentparam = row[6]
                dependentway = row[7]
                params = row[8]
                expected = row[9]
                Response_content = row[10]
                actual = row[11]
                exectime = sheet.cell_value(i, 12)

                if interfaceid != '':
                    interface_list = Webinterface.objects.filter(Q(projectid=projectid)
                                                                 & Q(interfaceid=interfaceid)
                                                                 & Q(moduleid=moduleid))
                    if interface_list.count() != 0:
                        if interface_list.count() == 1:
                            interface = interface_list[0]
                            Webinterface.objects.filter(
                                Q(projectid=projectid) & Q(interfaceid=interfaceid) & Q(moduleid=moduleid)) \
                                .update(interfaceid=interfaceid,
                                        url=url, method=method, dependent=dependent,
                                        dependentparam=dependentparam, dependentway=dependentway,
                                        actual=actual)
                            updatenum = updatenum + 1

                            response_list = Webresponse.objects.filter(Q(webinterfaceid=interface)
                                                                       & Q(exectime=exectime))
                            if exectime != '' and response_list.count() == 0:
                                Webresponse.objects.create(webinterfaceid=interface,
                                                           params=params, exectime=exectime,
                                                           expected=expected, Response_content=Response_content,
                                                           actual=actual
                                                           )
                        else:
                            return HttpResponse(json.dumps({"code": 400, "msg": "数据库中接口用例的ID不唯一，请检查"}))
                    else:
                        try:
                            # 写入数据库
                            interface = Webinterface(projectid=project,
                                                     moduleid=module,
                                                     interfaceid=interfaceid,
                                                     url=url, method=method,
                                                     dependent=dependent,
                                                     dependentparam=dependentparam, dependentway=dependentway,
                                                     actual=actual)

                            interface.save()
                            addnum = addnum + 1

                            response_list = Webresponse.objects.filter(Q(webinterfaceid=interface)
                                                                       & Q(exectime=exectime))
                            if exectime != '' and response_list.count() == 0:
                                Webresponse.objects.create(webinterfaceid=interface,
                                                           params=params, exectime=exectime,
                                                           expected=expected, Response_content=Response_content,
                                                           actual=actual
                                                           )
                        except Exception as e:
                            print(e)
                            return HttpResponse(json.dumps({"code": 400, "msg": "导入失败，请检查导入数据。"}))

    return HttpResponse(json.dumps({"code": 200,
                                    "msg": "导入成功,新增%d条数据，更新%d条数据。" % (addnum, updatenum)}))
